/**
 * UI 管理模块
 * 处理所有用户界面交互
 */

class UIManager {
    constructor() {
        this.currentResults = [];
        this.startTime = null;
    }

    /**
     * 初始化 UI 事件
     */
    initializeEvents() {
        // 标签页切换
        document.querySelectorAll('.tab-btn').forEach(btn => {
            btn.addEventListener('click', (e) => this.switchTab(e.target.dataset.tab));
        });

        // 上传区域
        const uploadArea = document.getElementById('uploadArea');
        uploadArea.addEventListener('click', () => {
            document.getElementById('videoInput').click();
        });

        uploadArea.addEventListener('dragover', (e) => {
            e.preventDefault();
            uploadArea.classList.add('dragover');
        });

        uploadArea.addEventListener('dragleave', () => {
            uploadArea.classList.remove('dragover');
        });

        uploadArea.addEventListener('drop', (e) => {
            e.preventDefault();
            uploadArea.classList.remove('dragover');
            const files = e.dataTransfer.files;
            if (files.length > 0) {
                this.handleVideoUpload(files[0]);
            }
        });

        // 文件输入
        document.getElementById('videoInput').addEventListener('change', (e) => {
            if (e.target.files.length > 0) {
                this.handleVideoUpload(e.target.files[0]);
            }
        });

        // 处理按钮
        document.getElementById('processBtn').addEventListener('click', () => {
            this.processUploadedVideo();
        });

        document.getElementById('clearBtn').addEventListener('click', () => {
            this.clearUploadedVideo();
        });

        // 摄像头按钮
        document.getElementById('startCameraBtn').addEventListener('click', () => {
            this.startCamera();
        });

        document.getElementById('stopCameraBtn').addEventListener('click', () => {
            this.stopCamera();
        });

        document.getElementById('captureBtn').addEventListener('click', () => {
            this.captureFromCamera();
        });

        // 设置
        document.getElementById('saveSettingsBtn').addEventListener('click', () => {
            this.saveSettings();
        });

        // 导出
        document.getElementById('exportJsonBtn').addEventListener('click', () => {
            this.exportJSON();
        });

        document.getElementById('exportTxtBtn').addEventListener('click', () => {
            this.exportTXT();
        });

        document.getElementById('copyResultsBtn').addEventListener('click', () => {
            this.copyResults();
        });

        // 加载保存的设置
        this.loadSettings();
    }

    /**
     * 切换标签页
     */
    switchTab(tabName) {
        // 隐藏所有标签页
        document.querySelectorAll('.tab-content').forEach(tab => {
            tab.classList.remove('active');
        });

        // 移除所有按钮的 active 类
        document.querySelectorAll('.tab-btn').forEach(btn => {
            btn.classList.remove('active');
        });

        // 显示选中的标签页
        document.getElementById(tabName).classList.add('active');
        document.querySelector(`[data-tab="${tabName}"]`).classList.add('active');
    }

    /**
     * 处理视频上传
     */
    handleVideoUpload(file) {
        if (!file.type.startsWith('video/')) {
            this.showStatus('请选择视频文件', 'error');
            return;
        }

        const url = URL.createObjectURL(file);
        const video = document.getElementById('uploadedVideo');
        video.src = url;
        video.classList.add('active');

        document.getElementById('processBtn').disabled = false;
        this.showStatus(`已选择视频: ${file.name}`, 'info');
    }

    /**
     * 清空上传的视频
     */
    clearUploadedVideo() {
        document.getElementById('uploadedVideo').src = '';
        document.getElementById('uploadedVideo').classList.remove('active');
        document.getElementById('videoInput').value = '';
        document.getElementById('processBtn').disabled = true;
        this.clearResults();
    }

    /**
     * 处理上传的视频 - 使用 SSE 流式处理
     */
    async processUploadedVideo() {
        const video = document.getElementById('uploadedVideo');
        if (!video.src) {
            this.showStatus('请先选择视频', 'error');
            return;
        }

        const file = document.getElementById('videoInput').files[0];
        if (!file) return;

        this.startProcessing();
        this.currentResults = [];

        try {
            const options = this.getSettings();

            // 使用 SSE 流式处理
            await ocrApi.processVideoStream(file, {
                sampleRate: options.sampleRate,
                minScore: options.minScore,
                onProgress: (data) => {
                    // 处理元数据事件
                    if (data.type === 'metadata') {
                        this.showStatus(`视频处理中... 总帧数: ${data.totalFrames}, FPS: ${data.fps}`, 'info');
                    }
                },
                onData: (data) => {
                    // 处理每一帧的结果
                    if (data.type === 'frame' && data.texts && data.texts.length > 0) {
                        // 添加新的识别结果
                        this.currentResults.push(...data.texts);
                        // 实时更新显示
                        this.displayResults(this.currentResults);
                        // 更新进度
                        this.updateProgress({
                            type: 'frame',
                            frameIndex: data.frameIndex,
                            timestamp: data.timestamp
                        });
                    }
                },
                onComplete: (data) => {
                    // 处理完成事件
                    this.showStatus(`视频处理完成 - 识别文本数: ${data.totalTexts}, 耗时: ${data.processingTime.toFixed(2)}s`, 'success');
                },
                onError: (data) => {
                    // 处理错误事件
                    this.showStatus(`处理错误: ${data.message}`, 'error');
                }
            });
        } catch (error) {
            this.showStatus(`错误: ${error.message}`, 'error');
        } finally {
            this.stopProcessing();
        }
    }

    /**
     * 启动摄像头
     */
    async startCamera() {
        try {
            // 检查浏览器是否支持 MediaDevices API
            if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
                throw new Error('您的浏览器不支持摄像头功能。请使用最新版本的 Chrome、Firefox、Safari 或 Edge。');
            }

            const stream = await navigator.mediaDevices.getUserMedia({
                video: { facingMode: 'user' },
                audio: false
            });

            const video = document.getElementById('cameraVideo');
            video.srcObject = stream;
            video.classList.add('active');

            document.getElementById('startCameraBtn').disabled = true;
            document.getElementById('stopCameraBtn').disabled = false;
            document.getElementById('captureBtn').disabled = false;

            // 连续识别模式
            if (document.getElementById('continuousMode').checked) {
                this.startContinuousCapture();
            }

            this.showStatus('摄像头已启动', 'success');
        } catch (error) {
            let errorMsg = error.message;

            // 处理常见的摄像头错误
            if (error.name === 'NotAllowedError') {
                errorMsg = '摄像头权限被拒绝。请在浏览器设置中允许访问摄像头。';
            } else if (error.name === 'NotFoundError') {
                errorMsg = '未找到摄像头设备。请检查硬件连接。';
            } else if (error.name === 'NotReadableError') {
                errorMsg = '摄像头被其他应用占用。请关闭其他使用摄像头的应用。';
            } else if (error.name === 'SecurityError') {
                errorMsg = '安全错误：请确保使用 HTTPS 或 localhost。';
            }

            this.showStatus(`摄像头启动失败: ${errorMsg}`, 'error');
            console.error('摄像头错误详情:', error);
        }
    }

    /**
     * 停止摄像头
     */
    stopCamera() {
        const video = document.getElementById('cameraVideo');
        if (video.srcObject) {
            video.srcObject.getTracks().forEach(track => track.stop());
        }

        video.classList.remove('active');
        document.getElementById('startCameraBtn').disabled = false;
        document.getElementById('stopCameraBtn').disabled = true;
        document.getElementById('captureBtn').disabled = true;

        this.stopContinuousCapture();
        this.showStatus('摄像头已停止', 'info');
    }

    /**
     * 从摄像头拍照 - 使用 SSE 流式处理
     */
    async captureFromCamera() {
        const video = document.getElementById('cameraVideo');
        const canvas = document.getElementById('cameraCanvas');
        const ctx = canvas.getContext('2d');

        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        ctx.drawImage(video, 0, 0);

        canvas.toBlob(async (blob) => {
            this.startProcessing();
            this.currentResults = [];

            try {
                const options = this.getSettings();

                // 使用 SSE 流式处理
                await ocrApi.processImageStream(blob, {
                    minScore: options.minScore,
                    onProgress: (data) => {
                        // 处理元数据事件
                        if (data.type === 'metadata') {
                            this.showStatus(`图像处理中... 尺寸: ${data.imageShape[0]}x${data.imageShape[1]}`, 'info');
                        }
                    },
                    onData: (data) => {
                        // 处理图像结果
                        if (data.type === 'frame' && data.texts && data.texts.length > 0) {
                            // 添加新的识别结果
                            this.currentResults = data.texts;
                            // 实时更新显示
                            this.displayResults(this.currentResults);
                        }
                    },
                    onComplete: (data) => {
                        // 处理完成事件
                        this.showStatus(`图像处理完成 - 识别文本数: ${data.totalTexts}, 耗时: ${data.processingTime.toFixed(2)}s`, 'success');
                    },
                    onError: (data) => {
                        // 处理错误事件
                        this.showStatus(`处理错误: ${data.message}`, 'error');
                    }
                });
            } catch (error) {
                this.showStatus(`错误: ${error.message}`, 'error');
            } finally {
                this.stopProcessing();
            }
        }, 'image/jpeg', 0.9);
    }

    /**
     * 启动连续拍照
     */
    startContinuousCapture() {
        const interval = parseInt(document.getElementById('captureInterval').value) * 1000;
        this.captureInterval = setInterval(() => {
            this.captureFromCamera();
        }, interval);
    }

    /**
     * 停止连续拍照
     */
    stopContinuousCapture() {
        if (this.captureInterval) {
            clearInterval(this.captureInterval);
            this.captureInterval = null;
        }
    }

    /**
     * 显示结果
     */
    displayResults(texts) {
        this.currentResults = texts;
        const resultsList = document.getElementById('resultsList');
        
        if (texts.length === 0) {
            resultsList.innerHTML = '<p class="empty-state">未识别到文本</p>';
            document.getElementById('resultStats').style.display = 'none';
            document.getElementById('exportButtons').style.display = 'none';
            return;
        }

        resultsList.innerHTML = texts.map((item, index) => {
            const confidence = item.confidence || 0;
            let confidenceClass = 'low';
            if (confidence >= 0.8) confidenceClass = 'high';
            else if (confidence >= 0.5) confidenceClass = 'medium';

            return `
                <div class="result-item">
                    <div class="result-text">${index + 1}. ${this.escapeHtml(item.text)}</div>
                    <div class="result-confidence ${confidenceClass}">
                        ${(confidence * 100).toFixed(1)}%
                    </div>
                </div>
            `;
        }).join('');

        // 显示统计信息
        this.updateStats(texts);
        document.getElementById('resultStats').style.display = 'block';
        document.getElementById('exportButtons').style.display = 'flex';
    }

    /**
     * 更新统计信息
     */
    updateStats(texts) {
        document.getElementById('totalTexts').textContent = texts.length;

        const avgConfidence = texts.length > 0
            ? (texts.reduce((sum, item) => sum + (item.confidence || 0), 0) / texts.length * 100).toFixed(1)
            : 0;
        document.getElementById('avgConfidence').textContent = `${avgConfidence}%`;

        if (this.startTime) {
            const processingTime = ((Date.now() - this.startTime) / 1000).toFixed(2);
            document.getElementById('processingTime').textContent = `${processingTime}s`;
        }
    }

    /**
     * 清空结果
     */
    clearResults() {
        this.currentResults = [];
        document.getElementById('resultsList').innerHTML = '<p class="empty-state">暂无识别结果</p>';
        document.getElementById('resultStats').style.display = 'none';
        document.getElementById('exportButtons').style.display = 'none';
    }

    /**
     * 显示状态消息
     */
    showStatus(message, type = 'info') {
        const statusEl = document.getElementById('statusMessage');
        statusEl.textContent = message;
        statusEl.className = `status-message show ${type}`;

        setTimeout(() => {
            statusEl.classList.remove('show');
        }, 5000);
    }

    /**
     * 更新进度
     */
    updateProgress(progress) {
        const container = document.getElementById('progressContainer');
        const fill = document.getElementById('progressFill');
        const text = document.getElementById('progressText');

        container.style.display = 'block';
        fill.style.width = `${progress}%`;
        text.textContent = `处理中... ${progress}%`;
    }

    /**
     * 开始处理
     */
    startProcessing() {
        this.startTime = Date.now();
        document.getElementById('progressContainer').style.display = 'block';
        this.clearResults();
    }

    /**
     * 停止处理
     */
    stopProcessing() {
        document.getElementById('progressContainer').style.display = 'none';
    }

    /**
     * 保存设置
     */
    saveSettings() {
        const settings = {
            apiUrl: document.getElementById('apiUrl').value,
            sampleRate: parseInt(document.getElementById('sampleRate').value),
            minScore: parseFloat(document.getElementById('minScore').value),
            maxResults: parseInt(document.getElementById('maxResults').value)
        };

        localStorage.setItem('ocrSettings', JSON.stringify(settings));
        ocrApi.setBaseUrl(settings.apiUrl);
        this.showStatus('设置已保存', 'success');
    }

    /**
     * 加载设置
     */
    loadSettings() {
        const saved = localStorage.getItem('ocrSettings');
        if (saved) {
            const settings = JSON.parse(saved);
            document.getElementById('apiUrl').value = settings.apiUrl || 'http://localhost:8000';
            document.getElementById('sampleRate').value = settings.sampleRate || 5;
            document.getElementById('minScore').value = settings.minScore || 0.5;
            document.getElementById('maxResults').value = settings.maxResults || 20;
            ocrApi.setBaseUrl(settings.apiUrl);
        }
    }

    /**
     * 获取设置
     */
    getSettings() {
        return {
            apiUrl: document.getElementById('apiUrl').value,
            sampleRate: parseInt(document.getElementById('sampleRate').value),
            minScore: parseFloat(document.getElementById('minScore').value),
            maxResults: parseInt(document.getElementById('maxResults').value)
        };
    }

    /**
     * 导出 JSON
     */
    exportJSON() {
        const data = {
            timestamp: new Date().toISOString(),
            results: this.currentResults
        };

        const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
        this.downloadFile(blob, 'ocr_results.json');
    }

    /**
     * 导出 TXT
     */
    exportTXT() {
        const text = this.currentResults
            .map((item, index) => `${index + 1}. ${item.text} (${(item.confidence * 100).toFixed(1)}%)`)
            .join('\n');

        const blob = new Blob([text], { type: 'text/plain' });
        this.downloadFile(blob, 'ocr_results.txt');
    }

    /**
     * 复制结果
     */
    copyResults() {
        const text = this.currentResults
            .map(item => item.text)
            .join('\n');

        navigator.clipboard.writeText(text).then(() => {
            this.showStatus('已复制到剪贴板', 'success');
        }).catch(() => {
            this.showStatus('复制失败', 'error');
        });
    }

    /**
     * 下载文件
     */
    downloadFile(blob, filename) {
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    }

    /**
     * HTML 转义
     */
    escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }
}

// 创建全局 UI 管理器实例
const uiManager = new UIManager();

